<?php
/**
 * Front controller for Concerto.
 *
 * Handles all data processing, security, database connectivity, sessions, file inclusions, etc
 *
 * @package Concerto
 * @subpackage System
 * @author Jason Raede <jason@torchdm.com>
 */
namespace application\system;
use application\utilities\Utility;
class Concerto {
	
	/**
	 * Singleton instance of the DB class
	 *
	 * @var \application\system\DB
	 */
	public $DB;
	
	/**
	 * Singleton instance of the UrlInterpreter class
	 *
	 * @var \application\system\UrlInterpreter
	 */
	public $UrlInterpreter;
	
	/**
	 * Singleton instance of the Cron class
	 *
	 * @var \application\system\Cron
	 */
	protected $Cron;
	
	/**
	 * Singleton instance of the ContentQuery class
	 *
	 * @var \application\initializers\ContentQuery
	 */
	public $ContentQuery;
	
	/**
	 * Singleton instance of the Modulator class
	 *
	 * @var \application\system\Modulator
	 */
	public $Modulator;
	
	/**
	 * Singleton instance of the UsersQuery class
	 *
	 * @var \application\initializers\UsersQuery
	 */
	public $UsersQuery;
	
	/**
	 * Singleton instance of the Loader class
	 *
	 * @var \application\initializers\Loader
	 */
	public $Loader;
	
	/**
	 * The current user
	 *
	 * @var \application\models\User
	 */
	public $User;
	
	/**
	 * @deprecated Don't know what I ever used this for?
	 */
	public $Display;
	
	/**
	 * Singleton instance of the Dev class, for development mode
	 *
	 * @var \application\utilities\Dev
	 */
	public $Dev;
	
	/**
	 * The HTTP request method
	 *
	 * @var string
	 */
	public $requestMethod;
	
	
	
	
	/**
	 * All query variables in the URL
	 *
	 * @var array
	 */
	public $queryVars = array();
	
	/**
	 * Query variables taken only from the "pretty" url, i.e. before the ?
	 *
	 * @var array
	 */
	public $urlQueryVars = array();
	
	/**
	 * Variables set in the URL query string that aren't
	 * registered query variables.
	 *
	 * @var array
	 */
	public $unusedQueryVars = array();
	
	//public $view = 'template';
	
	
	/**
	 * Initialize all singleton objects
	 */
	public function __construct() {
		
		// Error reporting
		if(defined('CN_DEBUG_MODE') && CN_DEBUG_MODE) {
 			error_reporting(E_ALL^E_NOTICE);
		}
		else {
 			error_reporting(0);
 			
		}
		
		// Database object
		$this->DB = new DB;
		$this->UrlInterpreter = new UrlInterpreter;
		$this->Cron = new Cron;
		$this->Modulator = new Modulator;
		$this->Dev = new \application\utilities\Dev;
		$this->Loader = new \application\initializers\Loader;
		$this->ContentQuery = new \application\initializers\ContentQuery;
		$this->UsersQuery = new \application\initializers\UsersQuery;
		
		
		date_default_timezone_set('America/Los_Angeles');
		
	}
	
	/**
	 * Initialize Concerto with just session, database, modules, and data handling.
	 */
	public function goMin() {
		$this->handleSession();
		// Connect to DB
		$this->DB->connect();
		
		$this->Modulator->includeModules();
		
		$this->handleData();
	}
	
	/**
	 * Initialize Concerto and run all processes
	 */
	public function go() {
		$this->handleSession();
		// Connect to DB
		$this->DB->connect();
		
		$this->Modulator->includeModules();
		
		$this->handleData();
		
		
		$this->UrlInterpreter->interpret();
		
		if(in_array(getQueryVar('view'), array('admin', 'template', 'view', 'form', 'json', 'api', 'rss', 'handler', 'content'))) {
			Modulator()->runFunction('url_interpret_end');
			$this->Cron->check();
			$this->initUser();
		}
		// Otherwise it's just serving a file so no need for cron or user verification
		$this->Loader->load();
		
	}
	
	/**
	 * Check if the user is logged in and create the user object if so
	 */
	protected function initUser() {
		// Check for logout
		if(getQueryVar('action') == 'logout') {
			unset($_SESSION['cn_user_id']);
			session_regenerate_id;
		}
		if($id = $_SESSION['cn_user_id']) {
			$user = new \application\models\User($_SESSION['cn_user_id']);
			$_SESSION['cn_user_id'] = $id; // Renew the session variable
		}
		else {
			$user = new \application\models\User;
		}
		
		$user = $this->Modulator->runFilter('user_auth', $user);
		
		
		// Make sure user has all required fields (email and password). 
		// If not, take them to the edit profile page and don't let them leave
		if($user->getData('user_id') && getQueryVar('view') != 'form' && getQueryVar('form') != 'edit_profile') {
			if(!$user->getData('user_email') || !$user->getData('user_password')) {
				header('location:'.CN_ROOT_URL.'?view=form&form=edit_profile&alert=required_fields');
				exit();
			}
		}
		$this->User = $user;
	}
	
	/**
	 * Parse all request data sent via HTTP, clean it, and organize it
	 */
	protected function handleData() {
		$registeredQueryVars = $this->Modulator->registeredQueryVars;
		$get = array();
		
		unset($_REQUEST);
		
		$this->requestMethod = strtolower($_SERVER['REQUEST_METHOD']);
		if($this->requestMethod == 'delete' || $this->requestMethod == 'put') {
			parse_str(file_get_contents('php://input'), $this->requestVars);
			
		
		}	
		
		foreach($_GET as $key=>$value) {
			if(in_array($key, $registeredQueryVars)) {
				$get[$key] = $value;
			}
			else {
				$this->unusedQueryVars[$key] = $value;
			}
		}
		if(get_magic_quotes_gpc()) {
			$_REQUEST = array_merge($get, $_POST);
			$this->queryVars = $get;
			$this->urlQueryVars = $get;
		}
		else {
			$get = Utility::arrayFunction($get, 'mysql_real_escape_string');
			$post = Utility::arrayFunction($_POST, 'mysql_real_escape_string');
			$this->unusedQueryVars = Utility::arrayFunction($this->unusedQueryVars, 'mysql_real_escape_string');
			$_REQUEST = array_merge($get, $post);
			$this->queryVars = $get;
			$this->urlQueryVars = $get;
		}
		
		$_REQUEST = Utility::arrayFunction($_REQUEST, 'cleanData');
		
		if($method = $_REQUEST['request_method']) {
			$this->requestMethod = $method;
		}
		
		
	}
	
	/**
	 * Session handling - needs to be expanded!
	 */
	protected static function handleSession() {
		//ini_set('session.cookie_domain', substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
		session_start();
	}
	
	/**
	 * Get a Concerto option from the database
	 *
	 * @param string $option
	 * @return string
	 */
	public static function getOption($option) {
		global $concerto;
		return $concerto->DB->getVar("SELECT `option_value` FROM `cn_options` WHERE `option_name`='$option'");
	}
	
	/**
	 * Set an option in the database
	 *
	 * @param string $option
	 * @param string $value
	 */
	public static function setOption($option, $value) {
		global $concerto;
		if($concerto->DB->getCount("SELECT `option_id` FROM `cn_options` WHERE `option_name`='$option'")) {
			$concerto->DB->query("UPDATE `cn_options` SET `option_value`='$value' WHERE `option_name`='$option'");
		}
		else {
			$concerto->DB->query("INSERT INTO `cn_options` (`option_name`, `option_value`) VALUES('$option', '$value')");
		}
	}
	
	
}

?>